// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
//
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.ui.tooltip;

import org.dengues.commons.utils.DenguesTextUtil;
import org.dengues.core.warehouse.IWarehouseNode;
import org.dengues.core.warehouse.WarehouseLabelUtil;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf Qiang.Zhang.Adolf@gmail.com 2008-4-29 qiang.zhang $
 * 
 */
public class WarehouseNodeToolTip extends ToolTip {

    private final static int X_SHIFT;

    static {
        if ("gtk".equals(SWT.getPlatform()) || "carbon".equals(SWT.getPlatform())) {
            X_SHIFT = -26;
        } else {
            X_SHIFT = -23;
        }
    }

    private final static int Y_SHIFT = 1;

    private IWarehouseNode node;

    private final Control control;

    /**
     * Qiang.Zhang.Adolf@gmail.com WarehouseNodeToolTip constructor comment.
     * 
     * @param control
     */
    public WarehouseNodeToolTip(Control control) {
        super(control);
        setShift(new Point(1, 1));
        this.control = control;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.ToolTip#createToolTipContentArea(org.eclipse.swt.widgets.Event,
     * org.eclipse.swt.widgets.Composite)
     */
    @Override
    protected Composite createToolTipContentArea(Event event, Composite parent) {
        Composite composite = createToolTipContentAreaComposite(parent);
        addIconAndLabel(composite, WarehouseLabelUtil.getNodeIcon(node), node.getLabel());
        String description = node.getDescription();
        if (description != null) {
            addIconAndLabel(composite, null, description);
        }
        return composite;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "addIconAndLabel".
     * 
     * @param parent
     * @param composite
     */
    private void addIconAndLabel(Composite composite, Image image, String label) {
        Label imageLabel = new Label(composite, SWT.NONE);
        imageLabel.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
        imageLabel.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
        imageLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING));
        imageLabel.setImage(image);

        Label textLabel = new Label(composite, SWT.NONE);
        textLabel.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
        textLabel.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
        textLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
        textLabel.setText(removeTrailingNewline(DenguesTextUtil.getNotNullString(label)));
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "removeTrailingNewline".
     * 
     * @param text
     * @return
     */
    private String removeTrailingNewline(String text) {
        if (text.endsWith("\n")) {
            return text.substring(0, text.length() - 1);
        }
        return text;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.ToolTip#getLocation(org.eclipse.swt.graphics.Point, org.eclipse.swt.widgets.Event)
     */
    @Override
    public Point getLocation(Point tipSize, Event event) {
        Widget widget = getTipWidget(event);
        Point location = super.getLocation(tipSize, event);
        if (widget != null) {
            Rectangle bounds = getBounds(widget);
            if (bounds != null) {
                Point location2 = control.toDisplay(bounds.x + X_SHIFT, bounds.y + bounds.height + Y_SHIFT);
                return new Point(location.x, location2.y);
            }
        }
        return location;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.window.ToolTip#shouldCreateToolTip(org.eclipse.swt.widgets.Event)
     */
    @Override
    protected boolean shouldCreateToolTip(Event event) {
        node = null;
        if (super.shouldCreateToolTip(event)) {
            Widget tipWidget = getTipWidget(event);
            if (tipWidget != null) {
                Rectangle bounds = getBounds(tipWidget);
                if (bounds != null && control.getBounds().contains(bounds.x, bounds.y)) {
                    node = getWarehouseNode(tipWidget);
                }
            }
        }
        if (node == null) {
            hide();
            return false;
        } else {
            return true;
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getWarehouseNode".
     * 
     * @param tipWidget
     * @return
     */
    private IWarehouseNode getWarehouseNode(Widget hoverObject) {
        if (hoverObject instanceof Widget) {
            Object data = (hoverObject).getData();
            if (data != null) {
                if (data instanceof IWarehouseNode) {
                    return (IWarehouseNode) data;
                }
            }
        }

        return null;
    }

    private Rectangle getBounds(Widget widget) {
        if (widget instanceof ToolItem) {
            ToolItem w = (ToolItem) widget;
            return w.getBounds();
        }
        if (widget instanceof TableItem) {
            TableItem w = (TableItem) widget;
            return w.getBounds();
        }
        if (widget instanceof TreeItem) {
            TreeItem w = (TreeItem) widget;
            return w.getBounds();
        }
        return null;
    }

    private Widget getTipWidget(Event event) {
        Point widgetPosition = new Point(event.x, event.y);
        Widget widget = event.widget;
        if (widget instanceof ToolBar) {
            ToolBar w = (ToolBar) widget;
            return w.getItem(widgetPosition);
        }
        if (widget instanceof Table) {
            Table w = (Table) widget;
            return w.getItem(widgetPosition);
        }
        if (widget instanceof Tree) {
            Tree w = (Tree) widget;
            return w.getItem(widgetPosition);
        }

        return widget;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "createToolTipContentAreaComposite".
     * 
     * @param parent
     * @return
     */
    private Composite createToolTipContentAreaComposite(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 2;
        gridLayout.marginWidth = 5;
        gridLayout.marginHeight = 2;
        composite.setLayout(gridLayout);
        composite.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
        return composite;
    }
}
